package cn.robot.board.net;

import android.os.AsyncTask;

import java.io.File;
import java.util.Map;
import java.util.concurrent.TimeUnit;

import okhttp3.FormBody;
import okhttp3.Headers;
import okhttp3.MediaType;
import okhttp3.MultipartBody;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;

public final class PostAsyncTask extends AsyncTask<String, Integer, String> {

    private static final MediaType JSON = MediaType.get("application/json; charset=utf-8");

    private Map<String, String> headers;
    private String bodyJson;
    private Map<String, String> formBody;
    private File file;
    private CallBackListener mCallBackListener;

    private String getRemoteInfo(String url) {
        String jsonData = null;
        try {
            OkHttpClient client = new OkHttpClient.Builder()
                    .retryOnConnectionFailure(true)
                    .connectTimeout(60, TimeUnit.SECONDS)
                    .readTimeout(60, TimeUnit.SECONDS)
                    .build();
            Request.Builder builder = new Request.Builder();

            if (headers != null) {
                builder.headers(Headers.of(headers));
            }

            RequestBody body = null;

            if (bodyJson != null) {
                body = RequestBody.create(JSON, bodyJson);
            } else if (formBody != null && file != null) {
                MultipartBody.Builder multipartBodyBuilder = new MultipartBody.Builder().setType(MultipartBody.FORM);
                for (Map.Entry<String, String> entry : formBody.entrySet()) {
                    multipartBodyBuilder.addFormDataPart(entry.getKey(), entry.getValue());
                }
                if (file != null) {
                    multipartBodyBuilder.addFormDataPart("file", file.getName(), RequestBody.create(MediaType.parse("image/png"), file));
                }
                body = multipartBodyBuilder.build();
            } else if (formBody != null) {
                FormBody.Builder formBodyBuilder = new FormBody.Builder();
                for (Map.Entry<String, String> entry : formBody.entrySet()) {
                    formBodyBuilder.add(entry.getKey(), entry.getValue());
                }
                body = formBodyBuilder.build();
            } else if (file != null) {
                MultipartBody.Builder multipartBodyBuilder = new MultipartBody.Builder().setType(MultipartBody.FORM);
                multipartBodyBuilder.addFormDataPart("file", file.getName(), RequestBody.create(MediaType.parse("image/png"), file));
                body = multipartBodyBuilder.build();
            }

            if (body == null) {
                throw new NullPointerException("body == null 请求体不能为空");
            }

            Request request = builder.url(url).post(body).build();

            try (Response response = client.newCall(request).execute()) {
                if (response != null && response.body() != null) {
                    jsonData = response.body().string();
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return jsonData;
    }

    @Override
    protected String doInBackground(String... params) {
        String ret = null;
        if (params != null) {
            ret = getRemoteInfo(params[0]);
        }
        return ret;
    }

    @Override
    protected void onPostExecute(String s) {
        if (mCallBackListener != null) {
            if (s != null) {
                mCallBackListener.onFinish(s);
            } else {
                mCallBackListener.onError("结果为空");
            }
        }
    }

    /**
     * 接口回调
     *
     * @param callBackListener 回调接口
     */
    void setCallBackListener(CallBackListener callBackListener) {
        this.mCallBackListener = callBackListener;
    }

    void setHeaders(Map<String, String> headers) {
        this.headers = headers;
    }

    void setBodyJson(String bodyJson) {
        this.bodyJson = bodyJson;
    }

    void setFormBody(Map<String, String> formBody) {
        this.formBody = formBody;
    }

    void setFile(File file) {
        this.file = file;
    }
}